// ==UserScript==
// @name         Patreon タグ自動挿入ヘルパー v2.1
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Patreonの新しいUIでタグを自動挿入（設定可能版）
// @author       You
// @match        https://www.patreon.com/posts/new*
// @match        https://www.patreon.com/posts/*/edit*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ========== 初期設定 ==========
    const CONFIG = {
        // ヘルパーの位置設定
        position: {
            top: '5px',      // 上からの距離
            right: '5px',    // 右からの距離
            left: 'auto',     // 左からの距離（rightを使う場合は'auto'のまま）
            bottom: 'auto'    // 下からの距離（topを使う場合は'auto'のまま）
        },

        // ヘルパーのサイズ設定
        size: {
            width: '370px',   // 幅
            maxHeight: '1000px' // 最大高さ
        },

        // デバッグ機能の初期表示状態
        debug: {
            initiallyVisible: false  // trueにするとデバッグボタンが最初から表示される
        }
    };

    // よく使うタグを設定
    const commonTags = [
        'ラブプラス',
        'R18',
        'R15',
        'R18+',
        'R15+',
        '姉ヶ崎寧々',
        '小早川凛子',
        '高嶺愛花',
        '－－－－－－－－－－－－－－－－－－－－－',
        '杜野凛世',
        '鷺沢文香',
        '新田美波',
        'あさり先生',
        '渋谷凛',
        '砂塚あきら',
        '前川みく',
        '及川零',
        '－－－－－－－－－－－－－－－－－－－－－',
        'DOAXVV水着',
        '格ゲー',
        'コスプレ',
        '－－－－－－－－－－－－－－－－－－－－－',
        'R18サンプル',
        '配布',
        'お知らせ'
    ];
    // ========== 初期設定ここまで ==========

    // グローバル変数でヘルパーの状態を管理
    let helperState = {
        isMinimized: false,
        isDragging: false,
        dragOffset: { x: 0, y: 0 },
        debugVisible: CONFIG.debug.initiallyVisible
    };

    // 詳細なページ構造解析
    function analyzePageStructure() {
        console.log('=== ページ構造解析開始 ===');

        // 全ての入力フィールドを探す
        const allInputs = document.querySelectorAll('input');
        console.log(`全入力フィールド数: ${allInputs.length}`);

        allInputs.forEach((input, index) => {
            const rect = input.getBoundingClientRect();
            const isVisible = rect.width > 0 && rect.height > 0 &&
                             window.getComputedStyle(input).display !== 'none';

            console.log(`入力${index + 1}:`, {
                type: input.type,
                placeholder: input.placeholder,
                value: input.value,
                className: input.className,
                id: input.id,
                visible: isVisible,
                position: { x: rect.x, y: rect.y, width: rect.width, height: rect.height }
            });
        });

        // 「タグ」関連のテキストを含む要素を探す
        const tagRelatedElements = Array.from(document.querySelectorAll('*')).filter(el => {
            const text = el.textContent || '';
            return text.includes('タグ') || text.includes('tag') || text.includes('Tag');
        });

        console.log(`タグ関連要素数: ${tagRelatedElements.length}`);
        tagRelatedElements.forEach((el, index) => {
            console.log(`タグ要素${index + 1}:`, {
                text: el.textContent?.trim().slice(0, 50),
                tagName: el.tagName,
                className: el.className
            });
        });

        return { allInputs, tagRelatedElements };
    }

    // 改良されたタグ入力フィールド検索
    function findTagInput() {
        console.log('タグ入力フィールドを検索中...');

        try {
            // 方法1: 「タグを追加する」テキストから検索（URLフィールドを除外）
            const tagSectionCandidates = Array.from(document.querySelectorAll('*')).filter(el => {
                const text = el.textContent || '';
                return text.includes('タグを追加') || text.includes('タグを入力');
            });

            console.log(`タグセクション候補数: ${tagSectionCandidates.length}`);

            for (const candidate of tagSectionCandidates) {
                console.log('タグセクション候補:', candidate.textContent?.slice(0, 30));

                // より安全な親要素の検索
                let currentElement = candidate;
                let searchDepth = 0;
                const maxDepth = 10;

                while (currentElement && searchDepth < maxDepth) {
                    const inputs = currentElement.querySelectorAll ?
                        currentElement.querySelectorAll('input[type="text"], input:not([type])') : [];

                    for (const input of inputs) {
                        const rect = input.getBoundingClientRect();
                        // URLフィールドを除外
                        const isUrlField = input.placeholder?.includes('URL') ||
                                         input.ariaLabel?.includes('URL') ||
                                         input.ariaLabel?.includes('Type or paste URL');

                        if (rect.width > 0 && rect.height > 0 && !isUrlField) {
                            console.log('方法1でタグ入力発見:', input);
                            return input;
                        }
                    }

                    currentElement = currentElement.parentElement;
                    searchDepth++;
                }
            }

            // 方法2: プレースホルダーテキストから検索
            const inputsWithPlaceholder = document.querySelectorAll('input[placeholder*="タグ"], input[placeholder*="tag"], input[placeholder*="Tag"]');
            if (inputsWithPlaceholder.length > 0) {
                console.log('方法2: プレースホルダーからタグ入力発見');
                return inputsWithPlaceholder[0];
            }

            // 方法3: aria-labelから検索（URLフィールドは除外）
            const inputsWithAriaLabel = document.querySelectorAll('input[aria-label*="タグ"], input[aria-label*="tag"], input[aria-label*="Tag"]');
            if (inputsWithAriaLabel.length > 0) {
                console.log('方法3: aria-labelからタグ入力発見');
                return inputsWithAriaLabel[0];
            }

            // 方法4: 「タグを追加する」セクション直下の入力フィールドを詳細検索
            for (const candidate of tagSectionCandidates) {
                // セクションの次の要素群を検索
                let nextElement = candidate.parentElement?.nextElementSibling;
                let attempts = 0;
                while (nextElement && attempts < 5) {
                    const inputs = nextElement.querySelectorAll('input');
                    for (const input of inputs) {
                        const rect = input.getBoundingClientRect();
                        const isUrlField = input.placeholder?.includes('URL') ||
                                         input.ariaLabel?.includes('URL');

                        if (rect.width > 0 && rect.height > 0 && !isUrlField &&
                            input.type !== 'file' && input.type !== 'hidden') {
                            console.log('方法4: セクション直下でタグ入力発見');
                            return input;
                        }
                    }
                    nextElement = nextElement.nextElementSibling;
                    attempts++;
                }
            }

            // 方法5: すべての表示されている入力フィールドから、URLフィールド以外で最も適切なものを選択
            const visibleInputs = Array.from(document.querySelectorAll('input')).filter(input => {
                if (input.type === 'file' || input.type === 'hidden' || input.type === 'checkbox' || input.type === 'radio') {
                    return false;
                }

                // URLフィールドを除外
                const isUrlField = input.placeholder?.includes('URL') ||
                                 input.ariaLabel?.includes('URL') ||
                                 input.ariaLabel?.includes('Type or paste URL');

                if (isUrlField) return false;

                const rect = input.getBoundingClientRect();
                const style = window.getComputedStyle(input);
                return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
            });

            console.log(`方法5: URLフィールド以外の表示入力フィールド数: ${visibleInputs.length}`);

            if (visibleInputs.length > 0) {
                // より小さく、下部にあるフィールドを優先（タグ入力は通常小さめで下部）
                const tagLikeInput = visibleInputs.reduce((best, current) => {
                    const currentRect = current.getBoundingClientRect();
                    const bestRect = best.getBoundingClientRect();

                    // 下部にあり、幅が狭い（タグ入力らしい）ものを優先
                    if (currentRect.top > bestRect.top && currentRect.width < bestRect.width * 1.5) {
                        return current;
                    }
                    return best;
                });

                console.log('方法5: タグ入力らしいフィールドを選択');
                return tagLikeInput;
            }

        } catch (error) {
            console.error('タグ入力検索中にエラー:', error);
        }

        return null;
    }

    // 改良されたタグ挿入機能（重複入力を防ぐ）
    function insertTag(tag) {
        console.log(`=== タグ挿入開始: "${tag}" ===`);

        const tagInput = findTagInput();
        if (!tagInput) {
            showMessage('タグ入力フィールドが見つかりません', 'error');
            return;
        }

        console.log('使用する入力フィールド:', tagInput);
        console.log('現在の値:', tagInput.value);

        try {
            // フォーカスを当てる
            tagInput.focus();

            // 現在の値を取得して、既に存在するかチェック
            const currentValue = tagInput.value || '';
            const existingTags = currentValue.split(',').map(t => t.trim()).filter(t => t);

            // 既に存在する場合はスキップ
            if (existingTags.includes(tag)) {
                showMessage(`タグ "${tag}" は既に追加されています`, 'warning');
                return;
            }

            const newValue = currentValue ? `${currentValue}, ${tag}` : tag;

            console.log('新しい値:', newValue);

            // より自然なタグ入力をシミュレート（自動補完との競合を避ける）

            // 1. まずフィールドをクリアして、フォーカスを確実に当てる
            tagInput.value = '';
            tagInput.focus();

            // 2. 少し待ってから文字を一文字ずつ入力（自然な入力をシミュレート）
            setTimeout(() => {
                let charIndex = 0;

                function typeChar() {
                    if (charIndex < newValue.length) {
                        const char = newValue[charIndex];

                        // 現在の値に一文字追加
                        const currentVal = tagInput.value;
                        tagInput.value = currentVal + char;

                        // 自然な入力イベントを発火
                        const inputEvent = new Event('input', {
                            bubbles: true,
                            cancelable: true,
                            composed: true
                        });
                        tagInput.dispatchEvent(inputEvent);

                        charIndex++;

                        // 次の文字を少し間隔をあけて入力
                        setTimeout(typeChar, 10);
                    } else {
                        // 入力完了後、Enterキーで確定
                        setTimeout(() => {
                            const enterEvent = new KeyboardEvent('keydown', {
                                key: 'Enter',
                                code: 'Enter',
                                keyCode: 13,
                                which: 13,
                                bubbles: true,
                                cancelable: true
                            });
                            tagInput.dispatchEvent(enterEvent);

                            // Enterのkeyupも送信
                            setTimeout(() => {
                                const enterUpEvent = new KeyboardEvent('keyup', {
                                    key: 'Enter',
                                    code: 'Enter',
                                    keyCode: 13,
                                    which: 13,
                                    bubbles: true,
                                    cancelable: true
                                });
                                tagInput.dispatchEvent(enterUpEvent);
                            }, 50);
                        }, 100);
                    }
                }

                typeChar();
            }, 100);

            // 結果確認は楽観的に（ほとんどの場合成功とみなす）
            setTimeout(() => {
                console.log('入力完了 - タグ:', tag);
                console.log('現在のフィールド値:', tagInput.value);

                // 基本的に成功メッセージを表示（タイピングが完了したので）
                showMessage(`タグ "${tag}" が追加されました`, 'success');

                // デバッグ用に最終状態をログ出力（警告は出さない）
                setTimeout(() => {
                    const finalValue = tagInput.value || '';
                    const finalTags = finalValue.split(',').map(t => t.trim()).filter(t => t);
                    console.log('最終確認 - フィールド値:', finalValue);
                    console.log('最終確認 - タグ配列:', finalTags);
                    console.log('最終確認 - タグ存在:', finalTags.includes(tag));
                }, 1000);

            }, 2000);

        } catch (error) {
            console.error('タグ挿入エラー:', error);
            showMessage(`エラー: ${error.message}`, 'error');
        }
    }

    // メッセージ表示関数
    function showMessage(text, type = 'info') {
        const colors = {
            success: '#28a745',
            error: '#dc3545',
            warning: '#ffc107',
            info: '#17a2b8'
        };

        const msg = document.createElement('div');
        msg.textContent = text;
        msg.style.cssText = `
            position: fixed;
            top: 70px;
            left: 50%;
            transform: translateX(-50%);
            background: ${colors[type] || colors.info};
            color: ${type === 'warning' ? '#000' : 'white'};
            padding: 12px 24px;
            border-radius: 6px;
            z-index: 30000;
            font-size: 14px;
            font-weight: 500;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            max-width: 400px;
            text-align: center;
        `;

        document.body.appendChild(msg);
        setTimeout(() => {
            if (msg.parentNode) {
                msg.remove();
            }
        }, 4000);
    }

    // ドラッグ機能の実装
    function makeDraggable(element) {
        let isDragging = false;
        let currentX;
        let currentY;
        let initialX;
        let initialY;
        let xOffset = 0;
        let yOffset = 0;

        function dragStart(e) {
            if (e.target.tagName === 'BUTTON') return; // ボタンをクリックした場合はドラッグしない

            if (e.type === "touchstart") {
                initialX = e.touches[0].clientX - xOffset;
                initialY = e.touches[0].clientY - yOffset;
            } else {
                initialX = e.clientX - xOffset;
                initialY = e.clientY - yOffset;
            }

            if (e.target === element.querySelector('.drag-handle') || e.target.closest('.drag-handle')) {
                isDragging = true;
                element.style.cursor = 'grabbing';
            }
        }

        function dragEnd(e) {
            initialX = currentX;
            initialY = currentY;
            isDragging = false;
            element.style.cursor = 'default';
        }

        function drag(e) {
            if (isDragging) {
                e.preventDefault();

                if (e.type === "touchmove") {
                    currentX = e.touches[0].clientX - initialX;
                    currentY = e.touches[0].clientY - initialY;
                } else {
                    currentX = e.clientX - initialX;
                    currentY = e.clientY - initialY;
                }

                xOffset = currentX;
                yOffset = currentY;

                element.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;
            }
        }

        element.addEventListener("touchstart", dragStart, false);
        element.addEventListener("touchend", dragEnd, false);
        element.addEventListener("touchmove", drag, false);

        element.addEventListener("mousedown", dragStart, false);
        element.addEventListener("mouseup", dragEnd, false);
        element.addEventListener("mousemove", drag, false);
    }

    // デバッグエリアの表示/非表示切り替え
    function toggleDebugArea() {
        const debugArea = document.getElementById('debug-area');
        if (debugArea) {
            if (helperState.debugVisible) {
                debugArea.style.display = 'none';
                helperState.debugVisible = false;
            } else {
                debugArea.style.display = 'block';
                helperState.debugVisible = true;
            }
        }
    }

    // タグヘルパーUIを作成
    function createTagHelper() {
        // 既存のヘルパーを削除
        const existingHelper = document.getElementById('tag-helper-v3');
        if (existingHelper) existingHelper.remove();

        const helper = document.createElement('div');
        helper.id = 'tag-helper-v3';

        // 設定された位置とサイズを適用
        const positionStyles = Object.entries(CONFIG.position)
            .map(([key, value]) => `${key}: ${value}`)
            .join('; ');

        helper.style.cssText = `
            position: fixed;
            ${positionStyles};
            background: white;
            border: 2px solid #ff424d;
            border-radius: 12px;
            padding: 0;
            box-shadow: 0 8px 24px rgba(0,0,0,0.15);
            z-index: 25000;
            width: ${CONFIG.size.width};
            max-height: ${CONFIG.size.maxHeight};
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            transition: all 0.3s ease;
            overflow: hidden;
        `;

        // ドラッグハンドル付きヘッダー
        const header = document.createElement('div');
        header.className = 'drag-handle';
        header.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px;
            border-bottom: 1px solid #eee;
            cursor: grab;
            user-select: none;
        `;

        const title = document.createElement('h3');
        title.textContent = 'タグヘルパー v2.1';
        title.style.cssText = `
            margin: 0;
            color: #ff424d;
            font-size: 16px;
            font-weight: 600;
            pointer-events: none;
        `;

        // ボタンコンテナ
        const buttonGroup = document.createElement('div');
        buttonGroup.style.cssText = `
            display: flex;
            gap: 8px;
        `;

        // 歯車ボタン（デバッグ機能切り替え）
        const settingsBtn = document.createElement('button');
        settingsBtn.innerHTML = '⚙️';
        settingsBtn.style.cssText = `
            background: none;
            border: none;
            font-size: 16px;
            cursor: pointer;
            color: #999;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            transition: background-color 0.2s;
        `;
        settingsBtn.onmouseover = () => settingsBtn.style.backgroundColor = '#f0f0f0';
        settingsBtn.onmouseout = () => settingsBtn.style.backgroundColor = 'transparent';
        settingsBtn.onclick = () => toggleDebugArea();

        // 最小化ボタン
        const minimizeBtn = document.createElement('button');
        minimizeBtn.textContent = '－';
        minimizeBtn.style.cssText = `
            background: none;
            border: none;
            font-size: 16px;
            cursor: pointer;
            color: #999;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            transition: background-color 0.2s;
        `;
        minimizeBtn.onmouseover = () => minimizeBtn.style.backgroundColor = '#f0f0f0';
        minimizeBtn.onmouseout = () => minimizeBtn.style.backgroundColor = 'transparent';
        minimizeBtn.onclick = () => toggleMinimize();

        // 閉じるボタン
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            background: none;
            border: none;
            font-size: 18px;
            cursor: pointer;
            color: #999;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            transition: background-color 0.2s;
        `;
        closeBtn.onmouseover = () => closeBtn.style.backgroundColor = '#f0f0f0';
        closeBtn.onmouseout = () => closeBtn.style.backgroundColor = 'transparent';
        closeBtn.onclick = () => helper.style.display = 'none';

        buttonGroup.appendChild(settingsBtn);
        buttonGroup.appendChild(minimizeBtn);
        buttonGroup.appendChild(closeBtn);
        header.appendChild(title);
        header.appendChild(buttonGroup);

        // コンテンツエリア
        const content = document.createElement('div');
        content.id = 'helper-content';
        content.style.cssText = `
            padding: 16px;
            transition: all 0.3s ease;
            overflow-y: auto;
            max-height: calc(${CONFIG.size.maxHeight} - 60px);
        `;

        // タグボタンコンテナ
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = `
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-bottom: 12px;
        `;

        // タグボタンを作成
        commonTags.forEach(tag => {
            const btn = document.createElement('button');
            btn.textContent = tag;
            btn.style.cssText = `
                background: #f8f9fa;
                border: 1px solid #dee2e6;
                border-radius: 6px;
                padding: 8px 12px;
                font-size: 12px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                color: #333;
            `;

            btn.onmouseover = () => {
                btn.style.backgroundColor = '#ff424d';
                btn.style.borderColor = '#ff424d';
                btn.style.color = 'white';
                btn.style.transform = 'translateY(-1px)';
            };

            btn.onmouseout = () => {
                btn.style.backgroundColor = '#f8f9fa';
                btn.style.borderColor = '#dee2e6';
                btn.style.color = '#333';
                btn.style.transform = 'translateY(0)';
            };

            btn.onclick = () => insertTag(tag);
            buttonContainer.appendChild(btn);
        });

        // デバッグエリア（初期状態では非表示）
        const debugArea = document.createElement('div');
        debugArea.id = 'debug-area';
        debugArea.style.cssText = `
            display: ${helperState.debugVisible ? 'block' : 'none'};
            border-top: 1px solid #eee;
            padding-top: 12px;
            margin-top: 12px;
        `;

        // デバッグボタン
        const debugBtn = document.createElement('button');
        debugBtn.textContent = 'ページ構造を解析';
        debugBtn.style.cssText = `
            width: 100%;
            margin-bottom: 8px;
            padding: 8px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 12px;
        `;
        debugBtn.onclick = () => {
            analyzePageStructure();
            showMessage('ページ構造をコンソールに出力しました', 'info');
        };

        const testBtn = document.createElement('button');
        testBtn.textContent = 'タグ入力フィールドをテスト';
        testBtn.style.cssText = `
            width: 100%;
            padding: 8px;
            background: #28a745;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 12px;
        `;
        testBtn.onclick = () => {
            const input = findTagInput();
            if (input) {
                input.style.border = '3px solid red';
                showMessage('赤い枠で囲まれたフィールドがタグ入力として認識されています', 'success');
                setTimeout(() => {
                    input.style.border = '';
                }, 3000);
            } else {
                showMessage('タグ入力フィールドが見つかりません', 'error');
            }
        };

        debugArea.appendChild(debugBtn);
        debugArea.appendChild(testBtn);

        content.appendChild(buttonContainer);
        content.appendChild(debugArea);

        helper.appendChild(header);
        helper.appendChild(content);
        document.body.appendChild(helper);

        // ドラッグ機能を追加
        makeDraggable(helper);

        // 最小化機能
        function toggleMinimize() {
            const content = document.getElementById('helper-content');
            if (helperState.isMinimized) {
                // 展開
                content.style.display = 'block';
                content.style.maxHeight = `calc(${CONFIG.size.maxHeight} - 60px)`;
                content.style.opacity = '1';
                minimizeBtn.textContent = '－';
                helperState.isMinimized = false;
            } else {
                // 最小化
                content.style.display = 'none';
                content.style.maxHeight = '0';
                content.style.opacity = '0';
                minimizeBtn.textContent = '+';
                helperState.isMinimized = true;
            }
        }

        console.log('タグヘルパー v2.1 作成完了');
    }

    // 初期化
    function init() {
        console.log('Patreon タグヘルパー v2.1 初期化中...');

        // ページ読み込み完了を待つ
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => {
                setTimeout(createTagHelper, 2000);
            });
        } else {
            setTimeout(createTagHelper, 2000);
        }

        // DOM変更を監視してUI再生成（ただし、存在する場合は再生成しない）
        const observer = new MutationObserver(() => {
            if (!document.getElementById('tag-helper-v3')) {
                setTimeout(createTagHelper, 1000);
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    init();

})();